package cn.wolfcode.car.business.service.impl;


import cn.wolfcode.car.business.domain.BpmnInfo;
import cn.wolfcode.car.business.mapper.BpmnInfoMapper;
import cn.wolfcode.car.business.query.BpmnInfoQuery;
import cn.wolfcode.car.business.service.IBpmnInfoService;
import cn.wolfcode.car.common.base.page.TablePageInfo;
import cn.wolfcode.car.common.config.SystemConfig;
import com.github.pagehelper.PageHelper;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class BpmnInfoServiceImpl implements IBpmnInfoService {

    @Autowired
    private BpmnInfoMapper bpmnInfoMapper;

    @Autowired
    private RepositoryService repositoryService;


    @Override
    public TablePageInfo<BpmnInfo> query(BpmnInfoQuery qo) {
        PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        return new TablePageInfo<BpmnInfo>(bpmnInfoMapper.selectForList(qo));
    }


    @Override
    public void save(BpmnInfo bpmnInfo) {

        bpmnInfoMapper.insert(bpmnInfo);
    }

    @Override
    public BpmnInfo get(Long id) {
        return bpmnInfoMapper.selectByPrimaryKey(id);
    }


    @Override
    public void update(BpmnInfo bpmnInfo) {

        bpmnInfoMapper.updateByPrimaryKey(bpmnInfo);
    }


    @Override
    public List<BpmnInfo> list() {
        return bpmnInfoMapper.selectAll();
    }

    @Override
    public void deploy(String path, String type, String info) {
        try {
            FileInputStream inputStream = new FileInputStream(new File(SystemConfig.getProfile(), path));
            // 部署流程文件
            Deployment deploy = repositoryService.createDeployment()
                    .addInputStream(path, inputStream)
                    .deploy();

            // 管理流程文件 （添加 BpmnInfo 数据 ）
            BpmnInfo bpmnInfo = new BpmnInfo();
            bpmnInfo.setBpmnPath(path);
            bpmnInfo.setBpmnType(type);
            bpmnInfo.setDeployTime(new Date());
            bpmnInfo.setDeploymentId(deploy.getId());
            bpmnInfo.setInfo(info);
            // 当流程部署成功之后，就会有流程定义对象： ProcessDefinition
            ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult();
            //
            bpmnInfo.setBpmnName(definition.getName()); //  流程图名称
            bpmnInfo.setActProcessId(definition.getId()); // 流程定义id
            bpmnInfo.setActProcessKey(definition.getKey()); //   流程图key

            bpmnInfoMapper.insert(bpmnInfo);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


    }

    @Override
    public InputStream readResource(String deploymentId, String type) {

        // 方案1：通过流程定义对象获取
        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).latestVersion().singleResult();

        InputStream inputStream = null;
        if ("xml".equals(type)) {
            // 文件
            inputStream = repositoryService.getResourceAsStream(deploymentId, definition.getResourceName());
        }else {
            // 图片 （代码直接拷贝就行）
            BpmnModel model = repositoryService.getBpmnModel(definition.getId());
            ProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
            //generateDiagram(流程模型,需要高亮的节点,需要高亮的线条,后面三个参数都表示是字体)
            inputStream = generator.generateDiagram(model, Collections.EMPTY_LIST, Collections.EMPTY_LIST,
                    "宋体","宋体","宋体");
        }
        return  inputStream;
    }

    @Override
    public void delete(Long id) {
        /** 思路逻辑：1 删除 流程定义对象 BpmnInfo 和 文件 (注意，删除之前先查出来保留)，
         *           2 如果流程定义对应的流程实例启动了也要删除,
         *           3 还有activiti相关表（级联删除，删除所有关联的表的数据）
         */
        // 先把要删除的流程定义查询出来保存
        BpmnInfo bpmnInfo = bpmnInfoMapper.selectByPrimaryKey(id);
        // 删除流程定义对象
        bpmnInfoMapper.deleteByPrimaryKey(id);
        // 删除流程定义文件
        String profile = SystemConfig.getProfile();
        String bpmnPath = bpmnInfo.getBpmnPath();

        File file = new File(SystemConfig.getProfile(), bpmnInfo.getBpmnPath());
        if (file.exists()){
            file.delete();
        }
        // 如果流程定义对应的流程实例启动了也要删除 --  后续实现

        // activiti 流程相关表（级联删除，删除所有关联的表的数据）
        repositoryService.deleteDeployment(bpmnInfo.getDeploymentId(), true);
    }

    @Override
    public BpmnInfo selectByBpmnType(String carPackage) {

        return  bpmnInfoMapper.selectByBpmnType(carPackage);
    }
}
